#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

#define PRINT( x ) printf( # x ": %d\n", x )

static void dump_argv( int argc, char *argv[] );
static void dump_options( int argc, char *argv[] );

int main( int argc, char *argv[] )
{
	dump_argv( argc, argv );
	dump_options( argc, argv );
	dump_argv( argc, argv );
}

static void dump_options( int argc, char *argv[] )
{
	struct option long_options[] = {
		{ "help", 0, NULL, 'h' },
		{ "version", 0, NULL, 'v' },
		{ "add", 1, NULL, 'a' },
		{ "no", 0, NULL, 0 },
		{ NULL, 0, NULL, 0 }
	};
	const char *short_opt = "hva:k:j";
	int c, option_index;

	for( int i = 0; long_options[i].name != NULL; i++ ) {
		printf( "%s\t%d\tNULL\t%c\n", long_options[i].name, long_options[i].has_arg,
				long_options[i].val );
	}
	printf( "shortopt: %s\n", short_opt );

	PRINT( optind );
	opterr = 0;
	while( (c = getopt_long( argc, argv, short_opt, long_options, &option_index )) != -1 ) {
		if( '?' == c ) {
			fprintf( stderr, "option err, optopt: %c, opt: %s arg: %s\n", optopt, argv[optind - 1], optarg );
			break;
		}
		printf( "optind %d, c %c, option_index %d, optarg %s\n",
				optind, c, option_index, optarg );
		dump_argv( argc, argv );
	}
	printf( "parse end.\n" );
	dump_argv( argc, argv );

	PRINT( optind );
	printf( "remain args:\n" );
	while( optind < argc ) {
		printf( "%s\n", argv[optind++] );
	}
	PRINT( optind );
}

static void dump_argv( int argc, char *argv[] )
{
	for( int i = 1; i < argc; i++ ) {
		printf( "%d:%X: %s\t", i, (unsigned int)argv[i], argv[i] );
	}
	printf( "\n" );
}
